<%@ page language="java" contentType="text/html; charset=UTF-8" %>

<%@ page import="org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl" %>
<%@ page import="org.tmatesoft.svn.core.internal.wc.DefaultSVNOptions" %>
<%@ page import="java.io.File" %>
<%@ page import="org.tmatesoft.svn.core.wc.*" %>
<%@ page import="org.tmatesoft.svn.core.io.SVNRepository" %>

<%@ page import="com.test.SvnListTempStatic" %>
<%@ page import="com.test.CopyFile" %>
<%@ page import="com.test.editTypeEnum" %>
<%@ page import="org.tmatesoft.svn.core.*" %>
<%@ page import="java.util.*" %>
<%@ page import="com.google.common.collect.Lists" %>
<%@ page import="org.tmatesoft.svn.core.auth.ISVNAuthenticationManager" %>


<%@page import="org.springframework.web.context.WebApplicationContext" %>
<%@page import="org.springframework.web.context.support.WebApplicationContextUtils" %>
<%@ page import="com.component.yhqProperties" %>
<%@ page import="com.component.CustomInfo" %>
<%@ page import="com.test.*" %>
<%@ page import="org.slf4j.Logger" %>
<%@ page import="java.net.InetAddress" %>
<%@ page import="org.springframework.web.context.request.ServletRequestAttributes" %>
<%@ page import="org.springframework.web.context.request.RequestContextHolder" %>
<%@ page import="java.net.UnknownHostException" %>
<%@ page import="cn.hutool.extra.pinyin.PinyinUtil" %>
<%@ page import="cn.hutool.core.util.RuntimeUtil" %>
<%@ page import="org.apache.tomcat.jni.Thread" %>
<%@ page import="cn.hutool.core.io.FileUtil" %>
<%@ page import="cn.hutool.core.date.DateUtil" %>
<%@ page import="cn.hutool.core.date.DateUnit" %>


<%
    /**
     * <p>Title: 一键检出svn工具<／p>
     * <p>Description: 检出本地-覆盖标准包文件-提交svn-锁定-提交修改后svn -回显日志<／p>
     * <p>Company: 版本升级部<／p>
     * @author ygd

     * @date 2021-09-27

     */
%>

<%


    response.setHeader("X-Frame-Options", "ALLOWALL");

    List<String> checkFlagStr = new ArrayList<>();//存放配置检查报错信息

    WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
    yhqProperties yhqProperties = (com.component.yhqProperties) context.getBean("yhqProperties");


    String svnuser = yhqProperties.getSvnName();//svn用户名
    String svnPassword = yhqProperties.getSvnPass();//svn密码
    String kbPath = yhqProperties.getKbPath();
    String bigUpgragePath = yhqProperties.getBigUpgragePath();
    Logger log = LoggerFactoryEtodo.getLog();

    log.info("kbPath:" + kbPath);

    String localIp = getLocalIp();
    log.info("localIp:" + localIp);

    String ipAddress1 = getIpAddress();
    log.info("ip:" + ipAddress1);
    if (!localIp.equals(ipAddress1)) {
        log.info("非本地访问拦截请求");
        return;
    }
    log.info("svnuser = " + svnuser);
    String customerId = null2String(request.getParameter("customerId"));
    SvnListTempStatic svnListTempStatic = SvnListTempStatic.map.get(customerId);


    CustomInfo customInfo = svnListTempStatic.getCustomInfo();



    log.info("customInfoName"+customInfo.getCustomerName()+"===>"+customInfo.toString());
    String title = customInfo.getTitle();
    Boolean isECUpgrade = true;//是否为ecologyKB升级 true為kb false為emobile
    Boolean is8to9 = false;//是否是8升9
    if (title.contains("版本升级")) {
        is8to9 = true;
        isECUpgrade = true;
    } else if (title.toUpperCase().contains("EMOBILE") ||title.toUpperCase().contains("更新包") ||  title.toUpperCase().contains("EM6") || title.toUpperCase().contains("非标包")|| title.toUpperCase().contains("非标")) {
        isECUpgrade = false;
    } else if (title.toUpperCase().contains("KB")) {
        isECUpgrade = true;
    } else {
        //checkFlagStr.add("判断升级类型出错！");
    }


    //这里提前处理一下标准的一些配置是否正确
    if (svnuser.length() == 0) {
        checkFlagStr.add("svn账号未填写");
    }
    if (svnPassword.length() == 0) {
        checkFlagStr.add("svn密码未填写");
    }
    if (!is8to9 && kbPath.length() == 0) {
        checkFlagStr.add("kb升级路径未填写");
    }
    if (is8to9 && bigUpgragePath.length() == 0) {
        checkFlagStr.add("大版本升级路径未填写");
    }

    String basePath = "";//本地地址路径
    if (is8to9) {
        basePath = bigUpgragePath;
    } else {
        basePath = kbPath;
    }


    String taskinfo = svnListTempStatic.getTaskinfo();
    String standardinfo = "\\\\192.168.7.215\\ECOLOGY_customer\\" + customInfo.getUpgradePath().substring(0, 1) + "\\" + customInfo.getUpgradePath() + "\\QC" + taskinfo.split("\n")[0] + "\\" + (isECUpgrade ? "ecology" : "EMobile");
    log.info("isECUpgrade = " + isECUpgrade);
    log.info("is8to9 = " + is8to9);

    String svnpath = isECUpgrade ? customInfo.getSvnECPath() : customInfo.getSvnMobilePath();

    String mySelect = null2String(request.getParameter("mySelect"));

    //svn列表文本域中的值
    String svnlist = null2String(request.getParameter("svnlist"));

    if (svnlist.length() == 0)
        svnlist = svnListTempStatic.getSvnlist();

    String[] splits = svnlist.split(",");
    String redSVNStr = "";//标红文件列表
    for (String s : splits) {
        redSVNStr += "\r\n" + s;
    }


    //展示的信息
    String BaseStr = "";//qc任务基本信息
    StringBuilder operationInfo = new StringBuilder();//操作日志
    List<String> errorList = new ArrayList<>();//错误日志
    List<String> logList = new ArrayList<>();//获取的日志列表


    if (checkFlagStr.size() == 0) {
        String customerName = svnpath.substring(svnpath.lastIndexOf("/") + 1);
        try {
            String checkoutPath = basePath + File.separator + customerName;
            String endpass = "";
            String[] pass = customInfo.getVmIP().split("\\.");
            for (String s : pass) {
                endpass += s;
            }

            /**
             * 登录免输入密码
             */

            //String str = RuntimeUtil.execForStr("cmdkey /add:10.10.41.210 /user:test /pass:Smb134##101041210");
            String str = RuntimeUtil.execForStr("cmdkey /add:" + customInfo.getVmIP() + " /user:test /pass:Smb134##" + endpass);
            log.info(customInfo.getCustomerName() + "添加网络凭据" + str);

            BaseStr = "【qc任务信息】" + taskinfo + getClipboardBtn(taskinfo, "COPY") + "<br>【svn检出路径】" + checkoutPath + getClipboardBtn(checkoutPath, "COPY") + "<br><br>【标准文件路径】" + standardinfo + getClipboardBtn(standardinfo, "COPY") + "<br>【测试环境地址】"
                    + "\\\\" + customInfo.getVmIP() + "\\weaver\\ecology" + getClipboardBtn("\\\\" + customInfo.getVmIP() + "\\weaver\\ecology", "COPY") + "【本地测试环境地址】" + getClipboardBtn("" + customInfo.getLocalOa(), "COPY") + "<br>【历史文件路径】" + customInfo.getHistoryPath() + getClipboardBtn(customInfo.getHistoryPath(), "COPY") +

                    "<br> <br>  <a href='" + customInfo.getCustomerCardUrl() + "'  target=\"_blank\">【客户卡片】</a> " +
                    " <a href='" + customInfo.getVmIPOA() + "'  target=\"_blank\">【测试环境】</a> " +

                    "<br>【数据库】" + customInfo.getDbVersion() + "<br>【中间件】" + customInfo.getAsVersionName();

            //初始化支持svn://协议的库。 必须先执行此操作。
            SVNRepositoryFactoryImpl.setup();

            //相关变量赋值
            SVNURL repositoryURL = SVNURL.parseURIEncoded(svnpath);
            SVNURL[] repositoryURLs = {repositoryURL};
            ISVNOptions options = SVNWCUtil.createDefaultOptions(true);
            //实例化客户端管理类
            SVNClientManager clientManager = SVNClientManager.newInstance(
                    (DefaultSVNOptions) options, svnuser, svnPassword);
            ISVNRepositoryPool repositoryPool = clientManager.getRepositoryPool();
            SVNRepository repository = repositoryPool.createRepository(repositoryURL, true);
            //要把版本库的内容check out到的目录
            File wcDir = new File(checkoutPath);
            if (!wcDir.exists() && !wcDir.isDirectory()) {
                wcDir.mkdirs();

            }
            File[] files = wcDir.listFiles();
            //通过客户端管理类获得updateClient类的实例。
            SVNUpdateClient updateClient = clientManager.getUpdateClient();
            updateClient.setIgnoreExternals(false);
            if ("1".equals(mySelect)) {
                //检出
                if (files.length == 0) {
                    //执行check out操作，返回工作副本的版本号。
                    long workingVersion = updateClient.doCheckout(
                            repositoryURL, wcDir,
                            SVNRevision.HEAD, SVNRevision.HEAD, SVNDepth.INFINITY, false
                    );
                    operationInfo.append("检出成功！ 工作副本的版本号： " + workingVersion);
                } else {
                    operationInfo.append("检出目录不为空,请检查");
                }


            } else if ("2".equals(mySelect)) {
                //锁定
                SVNWCClient wcClient = clientManager.getWCClient();
                for (String s : splits) {
                    for (String s1 : s.split("\r\n")) {
                        try {
                            String localPath = formatterSvnPath(s1, basePath, customerName);
                            log.info("正在锁定：SVNPath:" + s1 + ">:localPath" + localPath);
                            if ("".equals(localPath)) {
                                errorList.add(s1);
                                continue;
                            }
                            File[] wcDirs = {new File(localPath)};
                            wcClient.doLock(wcDirs, true, "");
                        } catch (Exception e) {
                            log.error(e.getMessage());

                            errorList.add(e.getMessage());
                        }
                    }
                }
                operationInfo.append("文件已锁定");
            } else if ("3".equals(mySelect)) {
                String editType = null2String(request.getParameter("editType"));
                String commitMessage = taskinfo.replace("<br>", "\n");
                if (editType.equals("1")) {
                    commitMessage += editTypeEnum.STANARD.getName();
                } else if (editType.equals("2")) {
                    commitMessage += editTypeEnum.MODIFY.getName();
                } else if (editType.equals("3")) {
                    commitMessage += editTypeEnum.REDUCTION.getName();
                }

                SVNCommitInfo commit = null;
                try {
                    commit = commit(clientManager, new File(checkoutPath), false, commitMessage);
                } catch (Exception e) {
                    operationInfo.append("svn提交出错：" + e.getMessage());
                    operationInfo.append("<br>");
                }

                operationInfo.append("svn提交 提交人：" + commit.getAuthor());
                operationInfo.append("<br>");
                operationInfo.append("svn提交 错误信息：" + commit.getErrorMessage());
                operationInfo.append("<br>");
                operationInfo.append("svn提交 新版本：" + commit.getNewRevision());
                operationInfo.append("<br>");
                operationInfo.append("svn提交 提交信息：" + commitMessage);


                ISVNAuthenticationManager authenticationManager = repository.getAuthenticationManager();
                List<Map<String, Object>> changeFileList = getChangeFileList(commit.getNewRevision(), repositoryURL, options, authenticationManager);
                List<String> svnLogs = formatterSvnLog(changeFileList, svnpath, commit.getNewRevision());
                logList.addAll(svnLogs);
            } else if ("4".equals(mySelect)) {
                try {
                    log.info("standardPath = " + standardinfo + "checkoutPath=" + checkoutPath);
                    String standardPath = standardinfo.replace("标准文件请到", "").replace("下面提取", "");

                    CopyFile.copyFolder(standardPath, checkoutPath, true);
                    operationInfo.append("标准包覆盖成功！！");
                } catch (Exception e) {
                    errorList.add(e.getMessage());
                }

            } else if ("5".equals(mySelect)) {
                ISVNAuthenticationManager authenticationManager = repository.getAuthenticationManager();
                long latestRevision = repository.getLatestRevision();
                List<Map<String, Object>> changeFileList = getChangeFileList(latestRevision, repositoryURL, options, authenticationManager);
                List<String> svnLogs = formatterSvnLog(changeFileList, svnpath, latestRevision);
                logList.addAll(svnLogs);
            } else if ("6".equals(mySelect)) {
                //提交标准文件，并提交到svn
                String[] split = svnlist.split("\\r\\n");
                String standardPath = standardinfo.replace("标准文件请到", "").replace("下面提取", "");

                try {
                    CopyFile.copyFileSvn(split, standardPath, checkoutPath, customInfo.getHistoryPath());
                    operationInfo.append("移动标准文件成功！！");
                } catch (Exception e) {
                    operationInfo.append("移动错误" + e.getMessage());
                }
                //移动修改文件
            } else if ("7".equals(mySelect)) {
                //复制本地文件到svn
                //提交标准文件，并提交到svn
                String[] split = svnlist.split("\\r\\n");
                try {
                    CopyFile.copyFileSvn(split, checkoutPath);
                    operationInfo.append("移动工作副本成功！！");
                } catch (Exception e) {
                    operationInfo.append("移动错误" + e.getMessage());
                }
                //解除本地副本中所有的锁定
            } else if ("8".equals(mySelect)) {


                try {

                    SVNWCClient wcClient = clientManager.getWCClient();
                    File fileKb = new File(kbPath);
                    File[] filesKb = fileKb.listFiles();
                    File[] filesList = filesKb;
                    if (!bigUpgragePath.equals("")) {
                        File fileBig = new File(bigUpgragePath);
                        File[] filesBig = fileBig.listFiles();
                        filesList = concat(filesKb, filesBig);
                    }
                    for (File file : filesList) {
                        if (file.isFile()) {
                            continue;
                        }

                        SVNRevision endRevision = SVNRevision.create(-1);
                        List<File> list = listModifiedFiles(file, endRevision);
                        if (list.size() != 0) {
                            log.info(file.getPath());
                            log.info(String.valueOf(list.size()));
                        } else {
                            continue;
                        }
                        File[] str2 = list.toArray(new File[list.size()]);
                        try {
                            wcClient.doUnlock(str2, true);

                        } catch (Exception e) {
                            e.getMessage();
                        }
                    }

                } catch (Exception e) {
                    operationInfo.append("解除本地文件锁定" + e.getMessage());
                }
            } else if ("9".equals(mySelect) || "10".equals(mySelect) || ("11".equals(mySelect)) || ("12".equals(mySelect))) {
                System.out.println("wjh");
                //搭建本地测试环境
                if (yhqProperties.getEcologyUrl().length() == 0)
                    throw new Exception("请在svn.properties填写正确的本地搭建地址:ecologyUrl");


                if ("9".equals(mySelect) || ("12".equals(mySelect))) {
                    File file = new File("\\\\" + customInfo.getVmIP() + "\\weaver\\ecology");
                    if (!file.exists()) {
                        throw new Exception("测试环境未开启");
                    }
                    if (customInfo.getIsCopy() == 0) {
//                        new java.lang.Thread(() -> {
//                            try {
//                                CopyFile.copyEcology(customInfo,yhqProperties);
//                            } catch (Exception e) {
//                                log.info(e.getMessage());
//                            }
//                        }).start();
                        customInfo.setIsCopy(1);
                        try {
                            CopyFile.copyEcology(customInfo, yhqProperties, mySelect);
                        } catch (Exception e) {
                            customInfo.setIsCopy(0);
                            errorList.add(e.getMessage());
                        }
                    } else {
                        if (customInfo.getIsCopy() == 1)
                            throw new Exception("正在搭建测试环境");
                        if (customInfo.getIsCopy() == 2)
                            throw new Exception("正在移动标准包独有src");
                        if (customInfo.getIsCopy() == 3)
                            throw new Exception("正在历史文件独有src");
                    }
                } else if ("10".equals(mySelect)) {

                    File file = new File(standardinfo + "\\src");
                    if (!file.exists()) {
                        log.info("历史文件src不存在"+customInfo.getHistoryPath() + "\\src");
                        throw new Exception("标准文件src不存在");
                    }
                    if (customInfo.getIsCopy() == 0) {
                        customInfo.setIsCopy(2);
                        //标准文件
                        Date begin = new Date();
                        FileUtil.copy(new File(standardinfo + "\\src"), new File(customInfo.getLocalOa() + "\\ecology"), false);
                        Date end = new Date();

                        customInfo.setIsCopy(0);
                        throw new Exception("用时" + DateUtil.between(begin, end, DateUnit.SECOND) + "秒");
                    } else {
                        if (customInfo.getIsCopy() == 1)
                            throw new Exception("正在搭建测试环境");
                        if (customInfo.getIsCopy() == 2)
                            throw new Exception("正在移动标准包独有src");
                        if (customInfo.getIsCopy() == 3)
                            throw new Exception("正在历史文件独有src");
                    }
                } else if ("11".equals(mySelect)) {
                    File file = new File(customInfo.getHistoryPath() + "\\src");
                    if (!file.exists()) {
                        log.info("历史文件src不存在"+customInfo.getHistoryPath() + "\\src");
                        throw new Exception("历史文件src不存在");
                    }
                    if (customInfo.getIsCopy() == 0) {
                        customInfo.setIsCopy(3);
                        //历史环境
                        Date begin = new Date();
                        FileUtil.copy(new File(customInfo.getHistoryPath() + "\\src"), new File(customInfo.getLocalOa() + "\\ecology"), false);
                        Date end = new Date();
                        customInfo.setIsCopy(0);
                        throw new Exception("用时" + DateUtil.between(begin, end, DateUnit.SECOND) + "秒");
                    } else {
                        if (customInfo.getIsCopy() == 1)
                            throw new Exception("正在搭建测试环境");
                        if (customInfo.getIsCopy() == 2)
                            throw new Exception("正在移动标准包独有src");
                        if (customInfo.getIsCopy() == 3)
                            throw new Exception("正在历史文件独有src");

                    }
                }
            }

        } catch (Exception e) {
            errorList.add(e.getMessage());
        }
    }
%>
<%!

    /**
     * 通过改变路径 获取提交日志
     * @param changeFileList 通过提交记录获取的版本提交改变的文件路径列表
     * @param svnpath 客户svn地址
     * @param latestRevision 需要拼接的版本号
     * @return 格式化好的提交记录日志
     */
    private List<String> formatterSvnLog(List<Map<String, Object>> changeFileList, String svnpath, long latestRevision) {
        List<String> svnLogs = new ArrayList<>();
        if (latestRevision < 0) {//当本地路径无可提交文件时，提交的版本号为-1，提醒
            svnLogs.add("无可提交的工作副本");
            return svnLogs;
        }
        for (Map<String, Object> map : changeFileList
        ) {

            String svnLog = svnpath + map.get("SvnPath") + "(V" + latestRevision + ")";
            if (null2String(map.get("SvnPath")).contains("."))//排除路径改变是文件夹的情况
                svnLogs.add(svnLog);
        }
        return svnLogs;
    }


    /**
     *
     * @return 返回本机ip地址
     */
    public static String getLocalIp() {
        InetAddress addr = null;
        try {
            //ip地址
            addr = InetAddress.getLocalHost();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        //主机名
        String hostname = addr.getHostName();
        return addr.getHostAddress();

    }

    /**
     * 获取Ip地址
     * @param request
     * @return
     */

    /**
     * 获取ip地址
     */
    public static String getIpAddress() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String ipAddress = request.getHeader("x-forwarded-for");
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("Proxy-Client-IP");
        }
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getRemoteAddr();
            if (ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")) {
                //根据网卡取本机配置的IP
                InetAddress inet = null;
                try {
                    inet = InetAddress.getLocalHost();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                ipAddress = inet.getHostAddress();
            }
        }
        //对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
        if (ipAddress != null && ipAddress.length() > 15) { //"***.***.***.***".length() = 15
            if (ipAddress.indexOf(",") > 0) {
                ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
            }
        }
        return ipAddress;
    }

    /**
     * 格式化svn路径到本地路径
     * @param svnpath 需要锁定的svn路径地址 可带版本号也可不带
     * @param basePath  本地的路径地址
     * @param customerName 客户名
     * @return 格式化好的本地路径
     */
    public String formatterSvnPath(String svnpath, String basePath, String customerName) {
        if (svnpath.startsWith("http")) {
            //通过客户名兼容本地路径 可以锁定不同客户svn的svn文件,解决客户换svn的情况
            String filepath = basePath + File.separator + customerName + svnpath.substring(svnpath.indexOf("/", svnpath.indexOf("/svn/") + 5));
            //三元表达式解决了没带版本号 锁定文件失败的问题
            filepath = filepath.substring(0, filepath.lastIndexOf("(") > 0 ? filepath.lastIndexOf("(") : filepath.length()).replace("/", "\\");
            return filepath;
        } else if (svnpath.startsWith("$")) {
            return formatterSvnPathForVss(svnpath, basePath, customerName);
        } else {
            return "";
        }
    }

    /**
     * 格式化vss路径到本地路径
     * @param svnpath 需要锁定的vss路径地址
     * @param basePath 本地路径地址
     * @param customerName 客户名称
     * @return 格式化好的本地路径
     */
    public String formatterSvnPathForVss(String svnpath, String basePath, String customerName) {
        String filepath = basePath + File.separator + customerName + svnpath.substring(svnpath.indexOf("/", svnpath.indexOf("$") + 2));
        filepath = filepath.substring(0, filepath.lastIndexOf("(") > 0 ? filepath.lastIndexOf("(") : filepath.length()).replace("/", "\\");
        return filepath;
    }

    /**
     * Commit work copy's change to svn
     * @param clientManager
     * @param wcPath
     *			working copy paths which changes are to be committed
     * @param keepLocks
     *			whether to unlock or not files in the repository
     * @param commitMessage
     *			commit log message
     * @return
     * @throws SVNException
     */
    public static SVNCommitInfo commit(SVNClientManager clientManager,
                                       File wcPath, boolean keepLocks, String commitMessage) throws SVNException {
        try {
            return clientManager.getCommitClient().doCommit(
                    new File[]{wcPath}, keepLocks, commitMessage, null,
                    null, false, false, SVNDepth.INFINITY);
        } catch (SVNException e) {
            throw e;
        }
    }


    /**获取一段时间内，所有的commit记录
     * @param st    开始时间
     * @param et    结束时间
     * @return
     * @throws SVNException
     */
    public SVNLogEntry[] getLogByVision(long startRevision, SVNRepository repository) throws SVNException {

        @SuppressWarnings("unchecked")
        Collection<SVNLogEntry> logEntries = repository.log(new String[]{""}, null,
                startRevision, startRevision, true, true);
        SVNLogEntry[] svnLogEntries = logEntries.toArray(new SVNLogEntry[0]);
        SVNLogEntry[] svnLogEntries1 = Arrays.copyOf(svnLogEntries, svnLogEntries.length - 1);
        return svnLogEntries1;
    }


    /**获取某一版本有变动的文件路径
     * @param version
     * @return
     * @throws SVNException
     */
    public List<Map<String, Object>> getChangeFileList(long version, SVNURL url, ISVNOptions options, ISVNAuthenticationManager authManager) throws SVNException {
        List<Map<String, Object>> ls = Lists.newArrayList();
        SVNLogClient logClient = new SVNLogClient(authManager, options);
        String[] paths = {"."};
        SVNRevision pegRevision = SVNRevision.create(version);
        SVNRevision startRevision = SVNRevision.create(version);
        SVNRevision endRevision = SVNRevision.create(version);
        long limit = 9999L;
        ISVNLogEntryHandler handler = new ISVNLogEntryHandler() {
            /**
             * This method will process when doLog() is done
             */
            @Override
            public void handleLogEntry(SVNLogEntry logEntry) {
                Map<String, SVNLogEntryPath> maps = logEntry.getChangedPaths();
                Set<Map.Entry<String, SVNLogEntryPath>> entries = maps.entrySet();
                for (Map.Entry<String, SVNLogEntryPath> entry : entries) {
                    Map<String, Object> svnDataAuxiliaryFour = new HashMap<>();
                    svnDataAuxiliaryFour.put("getRevision", logEntry.getRevision());
                    svnDataAuxiliaryFour.put("SvnPath", entry.getValue().getPath());
                    svnDataAuxiliaryFour.put("SvnType", String.valueOf(entry.getValue().getType()));
                    svnDataAuxiliaryFour.put("entry", entry.getValue());
                    ls.add(svnDataAuxiliaryFour);
                }
            }
        };
        try {
            logClient.doLog(url, paths, pegRevision, startRevision, endRevision, false, true, limit, handler);
        } catch (SVNException e) {
            LoggerFactoryEtodo.getLog().error(e.getMessage());

            throw e;
        }
        return ls;
    }

    public static String null2String(String s) {
        return s == null ? "" : s;

    }

    public static String null2String(String s, String def) {
        return s == null ? (def == null ? "" : def) : s;

    }

    public static String null2String(Object s) {
        return s == null ? "" : s.toString();

    }

    /**
     *  获取可粘贴的按钮html
     * @param text 需要点击按钮粘贴的内容
     * @param btnName 需要展示的按钮名称
     * @return
     */
    public static String getClipboardBtn(String text, String btnName) {

        String templateElement = "<div class=\"text-info\" data-clipboard-text=\"!@#$%^&\" style=\"display: inline; margin: 10px;cursor:pointer;\">*&^%$#</div>";

        return templateElement.replace("!@#$%^&", text).replace("*&^%$#", btnName);
    }

    //wjh
    public static List<File> listModifiedFiles(File path, SVNRevision revision) throws SVNException {
        SVNClientManager svnClientManager = SVNClientManager.newInstance();

        Logger log = LoggerFactoryEtodo.getLog();
        final List<File> fileList = new ArrayList<>();
        svnClientManager.getStatusClient().doStatus(path, revision, SVNDepth.INFINITY, false, false, false, false, new ISVNStatusHandler() {
            @Override
            public void handleStatus(SVNStatus status) throws SVNException {
                SVNStatusType statusType = status.getContentsStatus();

                if (statusType != SVNStatusType.STATUS_NONE) {
                    try {
                        fileList.add(new File(status.getFile().getPath()));
                        //只打印单纯锁定的。修改并锁定的不打印
                        if (statusType == SVNStatusType.STATUS_NORMAL) {
                            log.info("getFile= " + status.getFile().getPath());
                            log.info("statusType= " + statusType + "---SVNStatusType.LOCK_LOCKED=" + SVNStatusType.LOCK_LOCKED);

                        }
                    } catch (Exception e) {
                        log.error(e.getMessage());
                    }

                }

            }
        }, null);
        return fileList;
    }

    //数组合并
    static File[] concat(File[] a, File[] b) {
        File[] c = new File[a.length + b.length];
        System.arraycopy(a, 0, c, 0, a.length);
        System.arraycopy(b, 0, c, a.length, b.length);
        return c;
    }

%>


<html>

<head>


    <!-- 新 Bootstrap4 核心 CSS 文件 -->
    <link rel="stylesheet" href="/bootstrap.min.css">

    <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
    <script src="/jquery.min.js"></script>

    <!-- bootstrap.bundle.min.js 用于弹窗、提示、下拉菜单，包含了 popper.min.js -->
    <script src="/popper.min.js"></script>
    <script src="/clipboard.min.js"></script>

    <!-- 最新的 Bootstrap4 核心 JavaScript 文件 -->
     <script src="/bootstrap.min.js"></script>

    <link rel="shortcut icon" href="https://www.e-cology.com.cn/favicon.ico">




</head>
<title><%=customInfo.getCustomerName()%></title>
<body>
<div>

    <form action="test.jsp?customerId=<%=customerId%>" method="post">


        <%--    标准文件信息--%>
        <div class="card text-Success  border-Success  bg-light" style="width: 100%">
            <div class="card-header  ">
                <b>标准文件信息</b>
            </div>
            <div class="card-body ">
                <div class="text-success font-weight-bold " onmouseover="showCopy()" onmouseleave="hideCopy()" style="font-size: 14px;">
                    <%=BaseStr%>
                </div>
                <div id="alertMessage" style="
    position: fixed;
    margin-top: -8%;
    margin-left: 80%;
"></div>
            </div>
        </div>
        <p></p>


        <%--    日志相关信息--%>

        <div class="card  text-Warning  border-Warning   bg-light" style="width: 100%">
            <div class="card-header">
                <b>日志相关信息</b>
                <div style="float: right">
                    <button type="submit" value="" class="btn btn-warning btn-sm " onclick="select_type(1)">
                        检出svn
                    </button>

                    <button type="submit" value="" class="btn btn-warning btn-sm" onclick="select_type(4)">
                        覆盖标准包
                    </button>

                    <button type="submit" value="" class="btn btn-warning btn-sm" onclick="select_type(2)">
                        锁定标红文件
                    </button>

                    <button type="submit" value="" class="btn btn-warning btn-sm" onclick="select_type(5)">
                        获取日志
                    </button>
                    <button type="submit" value="" class="btn btn-warning btn-sm" onclick="select_type(6)">
                        提交标准文件
                    </button>

                    <button type="submit" value="" class="btn btn-warning btn-sm" onclick="select_type(7)">
                        移动副本文件
                    </button>
                    <%--解除副本锁定该功能（默认隐藏）--%>
                    <button type="submit" value="" class="btn btn-warning btn-sm" style="display: none" onclick="select_type(8)">
                        解除副本锁定
                    </button>

                    <div class="btn-group">
                        <button type="button" class="btn btn-danger  btn-sm dropdown-toggle" data-toggle="dropdown"
                                aria-expanded="false">
                            本地环境
                        </button>
                        <div class="dropdown-menu dropdown-menu-right dropdown-menu-lg-left">

                            <button type="submit"  class="dropdown-item" onclick="select_type(9)">一键搭建本地测试环境</button>
                            <button type="submit"  class="dropdown-item" onclick="select_type(10)">向本地测试环境覆盖升级包独有源码</button>
                            <button type="submit"  class="dropdown-item" onclick="select_type(11)">向本地测试环境覆盖历史文件独有源码</button>
                            <button type="submit"  class="dropdown-item" onclick="select_type(12)">向本地测试环境添加已排除目录文件</button>


                        </div>
                    </div>
                    <!-- Example single danger button -->
                    <div class="btn-group">
                        <button type="button" class="btn btn-danger  btn-sm dropdown-toggle" data-toggle="dropdown"
                                aria-expanded="false">
                            查看日志
                        </button>
                        <div class="dropdown-menu dropdown-menu-right dropdown-menu-lg-left">
                            <a  class="dropdown-item" target="_blank" href="log.jsp?logtype=1&customerId=<%=customerId%>">ecology日志</a>
                            <a class="dropdown-item" target="_blank" href="log.jsp?logtype=2&customerId=<%=customerId%>">Intergation日志</a>
                            <a class="dropdown-item" target="_blank" href="log.jsp?logtype=3&customerId=<%=customerId%>">systemRunInfo日志</a>
                            <a class="dropdown-item" target="_blank" href="log.jsp?logtype=4&customerId=<%=customerId%>">jvm日志</a>
                            <a class="dropdown-item" target="_blank" href="log.jsp?logtype=5&customerId=<%=customerId%>">stderr日志</a>
                            <a class="dropdown-item" target="_blank" href="log.jsp?logtype=6&customerId=<%=customerId%>">jvm日志【resin3】</a>
                        </div>
                    </div>

                </div>
            </div>

            <div class="card-body">

                <%
                    if (checkFlagStr.size() > 0) {
                %>
                <div class="alert alert-error alert-dismissible fade show">
                    <button type="button" class="close" data-dismiss="alert">&times;</button>
                    <strong>
                        <%
                            for (String s : checkFlagStr) {
                                /*配置检查的日志*/
                                out.println("<b>" + s + "</b><br>");
                            }
                        %>
                    </strong>
                </div>
                <%
                    }
                %>


                <%
                    if (operationInfo.toString().length() > 0) {
                %>
                <div class="alert alert-success alert-dismissible fade show">
                    <button type="button" class="close" data-dismiss="alert">&times;</button>
                    <strong>
                        <%
                            /*检出、覆盖标准包、提交snv的日志*/
                            out.println("<b>" + operationInfo.toString() + "</b>");
                        %>
                    </strong>
                </div>
                <%
                    }
                %>

                <%
                    /*错误日志*/
                    if (errorList.size() > 0) {
                        String errstr = "";
                        if (errorList.size() > 0) {
                            errstr += "出错文件列表<br>";
                            for (String s : errorList) {
                                errstr += s + "<br>";
                            }
                        }
                %>
                <div class="alert alert-warning alert-dismissible fade show">
                    <button type="button" class="close" data-dismiss="alert">&times;</button>
                    <strong><%=errstr%>
                    </strong>
                </div>
                <%
                    }
                %>

                <%
                    // 提交记录
                    if (logList.size() > 0) {
                        String editType = null2String(request.getParameter("editType"));
                        if (editType.equals("1")) {
                            editType = editTypeEnum.STANARD.getName();
                        } else if (editType.equals("2")) {
                            editType = editTypeEnum.MODIFY.getName();
                        } else if (editType.equals("3")) {
                            editType = editTypeEnum.REDUCTION.getName();
                        }
                        String logstr = "";
                        logstr += "\r\n";
                        logstr += editType.trim();
                        for (String s : logList) {
                            logstr += "\r\n";
                            logstr += s;
                        }
                %>
                <textarea type="textarea" class="form-control" rows="7" name="loglist" style="width: 100%">
                    <%=logstr%>
                   </textarea>
                <%
                    }
                %>
            </div>
        </div>

        <p></p>

        <div class="card text-Danger  border-Danger  bg-light" style="width: 100%">
            <div class="card-header ">
                <div class="form-inline">
                    <b>标红文件列表</b>
                    <div style="float: right">
                        <input name="svnpath" class="form-control form-control-sm" type="text" placeholder="请输入客户svn路径"
                               id="svnpath"
                               autoComplete="off"
                               style=" width: 380px;"
                               value="<%=svnpath%>">
                        <select id="editType" name="editType" class="form-control form-control-sm">
                            <option value="1" selected>标准文件</option>
                            <option value="2">修改后</option>
                            <option value="3">还原标准文件</option>
                        </select>
                        <button type="submit" value="" class="btn btn-danger btn-sm" onclick="select_type(3)">提交svn
                        </button>
                    </div>
                </div>
            </div>

            <div class="card-body">
                <textarea type="textarea" class="form-control" rows="20" style="width: 100%"
                          name="svnlist"><%=redSVNStr%></textarea>
            </div>
        </div>
</div>


<input type="hidden" name="taskinfo" value="<%=taskinfo%>">
<input type="hidden" name="standardinfo" value="<%=standardinfo%>">
<input type="hidden" name="mySelect" id="mySelect" value="">

</form>


<script>
    function select_type(type) {
        document.getElementById("mySelect").value = type;
    }

    hideCopy();
    $(document).ready(function () {

        var clipboard = new ClipboardJS('.text-info');
        clipboard.on('success', function (e) {
            console.info('Action:', e.action);　　//复制类型
            console.info('Text:', e.text);　　//复制文本
            console.info('Trigger:', e.trigger);　　//复制节点
            showCopyMessage("复制成功", e.text, "alert alert-success");
            e.clearSelection();　　//取消选择节点
        });

        clipboard.on('error', function (e) {
            console.error('Action:', e.action);
            console.error('Trigger:', e.trigger);
            showCopyMessage("复制失败", e.text, "alert alert-warning");
        });
    });

    function showCopyMessage(type, message, className) {
        var _html = "<div class=\"&^&^^%%%^&%&&\" role=\"alert\">\n" +
            "  <strong>&^%$&^%%$</strong><br>&^%%%^&%$^\n" +
            "  <button type=\"button\" class=\"close\" >\n" +
            "    <span aria-hidden=\"true\">&times;</span>\n" +
            "  </button>\n" +
            "</div>"


        _html = _html.replace("&^&^^%%%^&%&&", className).replace("&^%$&^%%$", type).replace("&^%%%^&%$^", message);

        $("#alertMessage").html(_html);

        colseModel(1000);
    }

    function colseModel(timer)
    {
        if (timer == null) {
            timer = 500;
        }
        window.setTimeout(function () {
            $(".alert").alert("close");
        }, timer);
    }


    function showCopy() {
        jQuery(".text-info").show();
    }

    function hideCopy() {
        jQuery(".text-info").hide()
    }

</script>
</div>
</body>
</html>


